package com.delicaterock.mpw;

import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class ConnectionScreen extends AbstractActivity {
    private String url;
    private String ips;
    private String port;
    private String secret;
    private String app;
    private String separator = "\t";
	private String id;

	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.connection);
        
        Intent i = this.getIntent();
        url = i.getStringExtra("url");
        id = i.getStringExtra("id");
        
        Button btnDelete = (Button) findViewById(R.id.btn_delete);        
        
        if (null!=id && id.length()>0) {        	
			SimpleDBHelper dbh = new SimpleDBHelper(ConnectionScreen.this);
			SQLiteDatabase db = dbh.getReadableDatabase();
			Cursor c = dbh.queryWalletByID(db, id);
			EditText txtName = (EditText) findViewById(R.id.txt_name); 
			EditText txtUsr = (EditText) findViewById(R.id.txt_user);
			EditText txtPwd = (EditText) findViewById(R.id.txt_pwd);
			
        	c.moveToFirst();
        	txtName.setText(c.getString(0));
        	txtUsr.setText(SimpleDBHelper.decrypt(c.getString(2)));
        	txtPwd.setText(SimpleDBHelper.decrypt(c.getString(3)));
        	//Log.d("current connection:", c.getString(1)); //FAPP field
        	db.close();
        	dbh.close();
        } else {
        	btnDelete.setVisibility(View.GONE);
	        if (null==url || url.length()==0) {
	        	url = "mpw://127.0.0.1:4444@0/unknown";	// sth. wrong
	        }
	        setBusy(true);
	        new HandleUrlTask().execute();
        }
        
        Button btnSave = (Button) findViewById(R.id.btn_save);
        btnSave.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				SimpleDBHelper dbh = new SimpleDBHelper(ConnectionScreen.this);
				EditText txtName = (EditText) findViewById(R.id.txt_name); 
				EditText txtUsr = (EditText) findViewById(R.id.txt_user);
				EditText txtPwd = (EditText) findViewById(R.id.txt_pwd);
				dbh.saveConnectionByName(txtName.getText().toString(), app, txtUsr.getText().toString(), txtPwd.getText().toString(), "", ips, port);
				dbh.close();
				finish();
			}});


		btnDelete .setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				showDeleteDialog();
			}});
        
    }
	
	private void showDeleteDialog() {  
		AlertDialog.Builder builder = new AlertDialog.Builder(ConnectionScreen.this);  
		builder.setIcon(R.drawable.icon);  
		builder.setTitle("Information");  
		builder.setMessage("Delete this connection?");  
		builder.setPositiveButton("Yes",  
			new DialogInterface.OnClickListener() {  
				public void onClick(DialogInterface dialog, int whichButton) {
					SimpleDBHelper dbh = new SimpleDBHelper(ConnectionScreen.this);
					SQLiteDatabase db = dbh.getReadableDatabase();
					dbh.deleteWalletByID(db, id);
					dbh.close();
					db.close();
					finish();					
				}
			});  
		builder.setNegativeButton("No",  
			new DialogInterface.OnClickListener() {  
				public void onClick(DialogInterface dialog, int whichButton) {  
		  
				}  
			});  
		builder.show();  
	}  	
	
	private class HandleUrlTask extends AsyncTask<Void, Void, Integer> {

		@Override
		protected Integer doInBackground(Void... params) {
			return handleUrl();
		}
		
		
		protected void onPostExecute(Integer rtn) {	
			setBusy(false);
			if (rtn==0) {
				Toast.makeText(ConnectionScreen.this, "Input your user and password for this new application.", Toast.LENGTH_LONG).show();				
			} else if (rtn==1) {
				Toast.makeText(ConnectionScreen.this, String.format("Send authentication [%s] finished.", app), Toast.LENGTH_LONG).show();
				finish();
			} else {			
				Toast.makeText(ConnectionScreen.this, String.format("Send authentication [%s] failed.", app), Toast.LENGTH_LONG).show();
				finish();
			}
		}		
	}
	
	private int handleUrl() {
		try {
			if (url.startsWith("mpw://")) {
				String prefixRemoved = url.replaceFirst("mpw://", "");
				ips = prefixRemoved.substring(0, prefixRemoved.indexOf(":"));
				port = prefixRemoved.substring(prefixRemoved.indexOf(":")+1, prefixRemoved.indexOf("@"));
				secret = prefixRemoved.substring(prefixRemoved.indexOf("@")+1, prefixRemoved.indexOf("/"));
				app = prefixRemoved.substring(prefixRemoved.indexOf("/")+1, prefixRemoved.length());
				Log.d("handleUrl():", String.format("ips:%s,port:%s,secret:%s,app:%s", ips, port, secret, app));
				
				// check if app exists
				SimpleDBHelper dbh = new SimpleDBHelper(this);
				SQLiteDatabase db = dbh.getReadableDatabase();
				Cursor conn = dbh.queryWalletByApp(db, app);
				if (null == conn || conn.getCount()==0) {
					// create new
					Log.d("","a new connection");
					db.close();
					dbh.close();
					return 0;
				} else {
					// connect
					conn.moveToFirst();
					String usr = SimpleDBHelper.decrypt(conn.getString(2));
					String pwd = SimpleDBHelper.decrypt(conn.getString(3));
					db.close();
					dbh.close();
					
					String[] iplist = ips.split(",");
					if (sendAuth(iplist, usr, pwd)) {
						return 1;
					} else {	
						return 2;						
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 2;
	}
	
	private boolean sendAuth(String[] iplist, String usr, String pwd) {		
		ArrayList<String> list = SimpleDBHelper.sortIPs(iplist);
		for (int i=0; i<list.size(); i++) {
			if (sendAuth(list.get(i), usr, pwd)) 
				{
					return true;
				}
		}		
		return false;
	}
	
	private boolean sendAuth(String ipStr, String usr, String pwd)		
	{		
		try {
			InetAddress ip = InetAddress.getByName(ipStr);
			if (!ip.isLoopbackAddress()) {	
					Log.d("sendAuth():", ip+":"+port);
					Socket socket = new Socket();
					socket.connect(new InetSocketAddress(ip, Integer.parseInt(port)), 6000);
					OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream(), "utf8");
					String payload = String.format("[mpw:%s]%s%s%s\n", secret, usr, separator,pwd);
					Log.d("sendAuth():", payload);
					out.write(payload);
					out.close();
					socket.close();
					return true;
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
		}	
		return false;
	}
}
